package com.onpositive.nlp.sequence;

import com.onpositive.nlp.inflector.SimplePOFParser;
import com.onpositive.nlp.sequence.ClassifiedSequence.Token;
import com.onpositive.wiki3.catmodels.ClassificatorCategoryModel;
import com.onpositive.wiki3.db.catmodel.matches.classify.YearMatcher;
import com.onpositive.wiki3.db.impl.WikiDBImpl;

public class SequenceParser {

	static class LinkAndLength {
		public LinkAndLength(int rs, int lp) {
			this.link = rs;
			this.end = lp;
		}

		int link;
		int end;
		String srt;
	}

	

	public static ClassifiedSequence parse(String str, ILookup p) {		
		ClassifiedSequence ss = new ClassifiedSequence();
		String[] split = str.split("_");
		for (int a = 0; a < split.length; a++) {
			String name = split[a];
			try{
				if (name.length()==0){
					continue;
				}
				if (Character.isDigit(name.charAt(0))){
				if (name.endsWith("s")) {
					name = name.substring(0, name.length() - 1);
				}
				if (name.endsWith("th")) {
					name = name.substring(0,name.length() - 2);
				}
				if (name.endsWith("th-century")) {
					name = name.substring(0, name.length()
							- "th-century".length());
				}
				Integer.parseInt(name);
				Token token = new Token(name, Token.NUMBER, -1);
				ss.add(token);
				continue;
				}				
			}catch (NumberFormatException e) {
				// TODO: handle exception
			}
			if  (YearMatcher.tags.contains(name)){
				Token token = new Token(name, Token.TEXT, -1);
				ss.add(token);
				continue;
			}
			if (ClassificatorCategoryModel.classificators.contains(name)) {
				Token token = new Token(name, Token.CLASIFICATOR, -1);
				ss.add(token);
				continue;
			}
			LinkAndLength m = lookup(split, a, p);
			if (m != null) {
				Token token = new Token(m.srt, Token.REFERENCE, m.link);
				ss.add(token);
				a = m.end - 1;
				String last = split[a];
				boolean noun = SimplePOFParser.isNoun(last);
				token.noun = noun;
				boolean veb = SimplePOFParser.isVerb(name);
				token.verb=veb;
				if (noun) {
					if (last.endsWith("s")) {
						token.plural = true;
					}
				}
				continue;
			}

			
			if (ClassificatorCategoryModel.classificators.contains(name)) {
				Token token = new Token(name, Token.CLASIFICATOR, -1);
				ss.add(token);

			} else {
				
				boolean noun = SimplePOFParser.isNoun(name);
				boolean veb = SimplePOFParser.isVerb(name);
				if (noun||veb){
					if (WikiLookup.neverReturn.contains(name))
					{
						Token token = new Token(name, Token.TEXT, -1);					
						ss.add(token);
						continue;
					}
					Token token = new Token(name, Token.NOUN, -1);
					token.noun=true;
					token.verb=veb;
					if (name.endsWith("s")) {
						token.plural = true;
					}
					ss.add(token);
				}
				else{
					Token token = new Token(name, Token.TEXT, -1);					
					ss.add(token);
				}
			}

		}
		ss.lock();
		return ss;
	}

	private static LinkAndLength lookup(String[] split, int a, ILookup p) {
		int rs = -1;
		int lp = -1;
		String ls = null;
		for (int i = a; i <= split.length; i++) {
			String s = subString(a, i, split);
			int j = p.get(s);
			if (j > 0) {
				ls = s;
				rs = j;
				lp = i;
			}
		}
		if (rs != -1) {
			LinkAndLength linkAndLength = new LinkAndLength(rs, lp);
			linkAndLength.srt = ls;
			return linkAndLength;
		}
		return null;
	}

	private static String subString(int a, int i, String[] split) {
		StringBuilder bld = new StringBuilder();
		for (int m = a; m < i; m++) {
			bld.append(split[m]);
			if (m != i - 1) {
				bld.append('_');
			}
		}
		return bld.toString();
	}

	public static ClassifiedSequence parse(String str, WikiDBImpl wikiDBImpl) {
		return parse(str, new WikiLookup(str, wikiDBImpl.getTitleMapper()));
	}
}
